package com.jhws.business.card.controller;

import java.util.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.jhws.business.card.bo.CardConstant;
import com.jhws.business.card.bo.CardUpdateData;
import com.jhws.common.PropertiesReader;
import com.jhws.core.dataUpdate.service.DataUpdateService;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.jhws.business.card.bo.TblCardDimBo;
import com.jhws.business.card.bo.TblCardPerms;
import com.jhws.business.comm.bo.TblCommDimBo;

import com.jhws.business.owner.bo.TblOwnerDimBo;
import com.jhws.common.base.bo.JsonRespData;
import com.jhws.util.GetId;
import com.jhws.common.base.bo.Global;
import com.jhws.util.AccountsUtils;
import com.jhws.business.card.bo.TblCardDimForm;

import com.jhws.business.comm.service.ITblBuildingDimService;
import com.jhws.business.card.service.ITblCardDimService;
import com.jhws.business.comm.service.ITblCommDimService;
import com.jhws.sys.menu.service.ITblMenuDimService;
import com.jhws.business.owner.service.ITblOwnerDimService;
import com.jhws.sys.user.service.ITblUserDimService;
import com.jhws.business.card.TblCardRecordServiceImpl;
import com.jhws.util.DateUtil;

@Controller
@RequestMapping("/card")
public class CardCtrl {

    @Resource
    protected ITblCardDimService ICardService;
    @Resource
    protected ITblMenuDimService IMenuService;
    @Resource
    protected ITblOwnerDimService IOwnerService;
    @Resource
    protected ITblCommDimService ICommService;
    @Resource
    protected ITblUserDimService IUserService;

    @Resource
    protected ITblBuildingDimService IUnitService;
    @Resource
    protected RedisTemplate stringTemplate;

    @Resource
    private TblCardRecordServiceImpl cardRecordService;

    @Resource
    private DataUpdateService dataUpdateService;

    @RequestMapping("queryCard.x")
    public ModelAndView cardList() throws Exception {

        ModelAndView mv = new ModelAndView();
        mv.setViewName("business/card/queryCard");
        return mv;
    }

    @RequestMapping("query.x")
    @ResponseBody
    public JsonRespData query(@RequestParam Map param) {
        return new JsonRespData("", 1, ICardService.findCardList(param));
    }

    @RequestMapping("queryBrushCard.x")
    public ModelAndView queryBrushCard() throws Exception {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("business/card/queryBrushCard");
        return mv;
    }

    @RequestMapping("queryBrush.x")
    @ResponseBody
    public Object queryBrush(@RequestParam Map param) throws Exception {
        String commCode = MapUtils.getString(param, "commCode", "");
        String userCommCode = IUserService.currentUser().getCommCode();
        /* 当前账号不是管理员，必须要校验获取的小区是否具有权限 */
        if (StringUtils.isNotEmpty(userCommCode)) {
            if (StringUtils.isEmpty(commCode))
                param.put("commCode", userCommCode); //如果没有带小区,则自动查询该用户具有权限的小区
            else if (!userCommCode.contains(commCode))
                return new JsonRespData("", -1, "您没有访问" + (commCode) + "小区的权限!");
        }
        return cardRecordService.findBrushCardList(param);
    }

    @RequestMapping("deleteBrushCard.x")
    @ResponseBody
    public Object deleteBrushCard(@RequestParam Map param) {
        String deleteCard = param.get("deleteCard").toString();
        String[] idList = deleteCard.split(",");
        for (String id : idList) {
            cardRecordService.delete(id);
        }
        return new JsonRespData("", 1, "");
    }

    /**
     * 删除卡相关一切信息
     *
     * @param cardNo
     * @return
     */
    @RequestMapping("delete.x")
    @ResponseBody
    public JsonRespData deleteCard(String cardNo) {
        ICardService.removeCard(cardNo);
        ICardService.removeCardPerms(cardNo);
        return new JsonRespData("", 1, "");
    }

    @RequestMapping("lost.x")
    @ResponseBody
    public JsonRespData lost(String cardNo, String LostOrResume, String endDate) throws Exception {
        if (cardNo == null)
            return null;

        HashOperations hashOperations = stringTemplate.opsForHash();

        /* 设置卡状态与卡权限状态为挂失 */
        TblCardDimBo bo = ICardService.findTblCardDimById(cardNo);

        Date now = new Date();
        if (CardConstant.CARD_TYPE_NORMAL.equals(bo.getCardType())) {
            List<TblCardPerms> permsList = ICardService.findCardPerms(cardNo);

            for (TblCardPerms perm : permsList) {
                /* 将更新的数据条目时间戳推送给Redis */
                hashOperations.put(CardConstant.REDIS_CARD_TIMESTAMP, perm.getDevBuildingNo(), now.toString());
                perm.setEnable(StringUtils.isNotEmpty(LostOrResume) ? CardConstant.CARD_PERM_WHITELIST : CardConstant.CARD_PERM_BLACKLIST);
                perm.setTimeStamp(now.getTime());
                ICardService.save(perm);
                dataUpdateService.pushAndUpdate(now.getTime(), CardUpdateData.CARD_PERMS, perm.getDevBuildingNo(), true, false, null, null);
            }
        } else {
            dataUpdateService.pushAndUpdate(now.getTime(), CardUpdateData.CARD_PERMS, bo.getCommCode(), false, false, null, null);
        }
        bo.setLastModifyTime(now);
        bo.setTimestamp(now.getTime());
        if ("expiryResume".equals(LostOrResume))
            bo.setEndDate(DateUtil.stringDate(endDate, "yyyy-MM-dd"));
        bo.setState(StringUtils.isNotEmpty(LostOrResume) ? CardConstant.CARD_STATUS_RESUME : CardConstant.CARD_STATUS_DISABLED);
        ICardService.save(bo);
        return new JsonRespData("", 1, "");
    }

    @RequestMapping("forSave.x")
    public String forSave(String old, HttpServletRequest request) throws Exception {
        // 将小区列表传给jsp
        List<TblCommDimBo> commList = IUserService.getUserComms(IUserService.currentUser());
        if (commList.size() != 0) {
            if (!SecurityUtils.getSubject().hasRole(Global.ROLE_PROPERTY_ADMIN))
                request.setAttribute("commDimList", commList);
            else
                request.setAttribute("commDimBo", commList.get(0));
        }

        String platform = PropertiesReader.getProperty("basePlatform");
        if (Global.SERVER_TYPE_PLATFROM.equals(platform))
            request.setAttribute("sp", CardConstant.CARD_SECURITY_PLATFORM_PREFIX);
        else if (Global.SERVER_TYPE_TIANZHU.equals(platform))
            request.setAttribute("sp", CardConstant.CARD_SECURITY_TIANZHU_PREFIX);
        else
            request.setAttribute("sp", CardConstant.CARD_SECURITY_JHCLOUD_PREFIX);

        if (old != null)
            return "business/card/addCard";
        else
            return "business/card/forSave";
    }

    @RequestMapping("save.x")
    @ResponseBody
    public JsonRespData saveCard(TblCardDimForm form)
            throws java.lang.Exception {

        String cardNo, state;
        /* 获取普通卡信息 */

        if (form.getCardType().equals("s")) {
            cardNo = form.getsCardNo();
            state = form.getsState();
        } else {
            cardNo = form.getnCardNo();
            state = form.getnState();
        }

        TblCardDimBo bo = ICardService.findTblCardDimById(cardNo);
        if (bo == null)
            bo = new TblCardDimBo();
        bo.setCardType(form.getCardType());
        bo.setCardNo(cardNo);
        bo.setOwnerCode(form.getOwnerCode());
        bo.setOwnerName(form.getOwnerName().replaceAll("\r|\n|\t", ""));
        bo.setState(state);

        bo.setCommCode(form.getCommCode());
        bo.setLastModifyTime(new Date());
        bo.setRoomName(form.getRoomName());

        Date now = new Date();
        if (bo.getBeginDate() == null)
            bo.setBeginDate(now);
        if (StringUtils.isNotEmpty(form.getEndDate()))
            bo.setEndDate(DateUtil.stringDate(form.getEndDate(), DateUtil.DATE_FORMAT));
        else
            bo.setEndDate(null);

        /* 假如是ID卡模式，则每发一张卡，需要推送给终端进行拉取 */
        TblCommDimBo comm = ICommService.findTblCommDimById(bo.getCommCode());
        Long timeStamp = System.currentTimeMillis();
        /* 如果是超级卡，推送标签全小区 */
        if (comm != null && CardConstant.CARD_VENDOR_LK_ID.equals(comm.getCardVendor()) && bo.getCardType().equals(CardConstant.CARD_TYPE_SUPPER)) {
            bo.setTimestamp(timeStamp);
            dataUpdateService.pushAndUpdate(timeStamp, CardUpdateData.CARD_PERMS, comm.getCommCode(),
                    false, false, "", "");
        }

        ICardService.save(bo);
        /* 获取卡权限信息 */
        String[] perms = form.getPermsStr();

        /* 每次都复写所有权限 ,因此先删除掉之前的 */
        ICardService.removeCardPerms(cardNo);
        for (int i = 0; !form.getCardType().equals("s") && i < perms.length; i++) {
            TblCardPerms perm = new TblCardPerms();
            String[] items = perms[i].replaceAll("\r|\n|\t", "").split(":");
            perm.setId(GetId.GetId2());
            perm.setCardNo(cardNo);
            perm.setDevNo(items[1]);
            perm.setDevStr(items[2]);
            perm.setEnable("Y");
            perm.setDevBuildingNo(items[3]);
            perm.setTimeStamp(timeStamp);
            if (comm != null && CardConstant.CARD_VENDOR_LK_ID.equals(comm.getCardVendor())) {
                dataUpdateService.pushAndUpdate(timeStamp, CardUpdateData.CARD_PERMS, perm.getDevBuildingNo(),
                        true, false, "", "");
            }
            ICardService.save(perm);
        }


        return new JsonRespData("", 1, "success");
    }

    @RequestMapping("findCard.x")
    @ResponseBody
    public JsonRespData findCard(String cardNo) {

        TblCardDimBo bo = ICardService.findTblCardDimById(cardNo);
        Map<String, Object> retMap = new HashMap<>();
        String platform = PropertiesReader.getProperty("basePlatform");
        /* 将卡秘钥前缀带下去 */
        if (Global.SERVER_TYPE_PLATFROM.equals(platform))
            retMap.put("sp", CardConstant.CARD_SECURITY_PLATFORM_PREFIX);
        else if (Global.SERVER_TYPE_TIANZHU.equals(platform))
            retMap.put("sp", CardConstant.CARD_SECURITY_TIANZHU_PREFIX);
        else
            retMap.put("sp", CardConstant.CARD_SECURITY_JHCLOUD_PREFIX);
        if (bo == null)
            return new JsonRespData("", 1, retMap);

        if (CardConstant.CARD_STATUS_DISABLED.equals(bo.getState())) {
            return new JsonRespData("", -1, "该卡已被挂失，请先去卡列表中恢复该卡，再来操作！");
        }

        String cardType = bo.getCardType();
        if (cardType == null)
            cardType = "n";

        if (cardType.equals("n") && bo == null) {
            retMap.put("ret_code", -1);
            retMap.put("data", "卡号 " + cardNo + " 未找到绑定业主！");
        }
        /* 普通卡 */
        else if (cardType.equals("n")) {
            List<TblCardPerms> permsList = ICardService.findCardPerms(cardNo);
            TblOwnerDimBo owner = IOwnerService.findTblOwnerDimById(bo.getOwnerCode());
            retMap.put("cardInfo", bo);
            retMap.put("cardPerms", permsList);
            if (owner != null)
                retMap.put("ownerStr", owner.getRoomInfo() + " " + owner.getOwnerName());
            retMap.put("ret_code", 1);
        }
        /* 超级卡 */
        else if (cardType.equals("s")) {
            TblCommDimBo comm = ICommService.findTblCommDimById(bo.getCommCode());
            retMap.put("cardInfo", bo);
            retMap.put("commName", comm.getCommName());
            retMap.put("ret_code", 1);
        }
        return new JsonRespData("", 1, retMap);
    }

    private String calDevNumberForCard(int type, String Room, int dev) {
        String resultStr;
        if (type == 0) {
            int area = Integer.valueOf(AccountsUtils.getBuilding(Room));
            int unit = Integer.valueOf(AccountsUtils.getUnit(Room));
            int result = dev | (unit << 3) | (area << 7);
            resultStr = Integer.toHexString(result);
        } else {
            resultStr = Integer.toHexString(dev);
        }

        if (resultStr.length() == 3)
            return "0" + resultStr;
        else if (resultStr.length() == 2)
            return "00" + resultStr;
        else if (resultStr.length() == 1)
            return "000" + resultStr;
        return resultStr;
    }

    /*
     * @author Alex Tan
     *
     * @date 2017年1月6日
     */
    @RequestMapping("getDefaultPerms.x")
    @ResponseBody
    public JsonRespData getDefaultPerms(String ownerCode) throws Exception {
        TblOwnerDimBo bo = IOwnerService.findTblOwnerDimById(ownerCode);
        List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();

        /* 获取默认单元门设备权限 */
        int UnitDevNum = IUnitService.getUnitDevNumber(bo.getRoomInfoNum());
        String areaAliasName = IUnitService.getBuildingAliasName(bo.getCommCode(), AccountsUtils.getBuilding(bo.getRoomInfoNum()), AccountsUtils.getUnit(bo.getRoomInfoNum()));
        String buildingAliasName = IUnitService.getUnitAliasName(bo.getCommCode(), AccountsUtils.getBuilding(bo.getRoomInfoNum()), AccountsUtils.getUnit(bo.getRoomInfoNum()));
        for (int i = 1; i <= UnitDevNum; i++) {
            HashMap<String, String> map = new HashMap<String, String>();
            map.put("devNo", calDevNumberForCard(0, bo.getRoomInfoNum(), i));
            map.put("devStr",
                    "[" + bo.getCommName() + "] " + areaAliasName + " " + buildingAliasName + " " + i + "号机");
            map.put("commCode", bo.getCommCode());
            map.put("devBuildingNo", bo.getRoomInfoNum().substring(0, 8) + "00" + (i > 9 ? i : "0" + i));
            list.add(map);
        }

        /* 获取默认围墙机权限 */
        TblCommDimBo comm = ICommService.findTblCommDimById(bo.getCommCode());
        int gateDevNum = comm.getGateDevNum();
        for (int i = 1; i <= gateDevNum; i++) {
            HashMap<String, String> map = new HashMap<String, String>();
            map.put("devNo", calDevNumberForCard(1, null, i));
            map.put("devStr", "[" + bo.getCommName() + "] 围墙机 " + (char) (i - 1 + 'A') + "号机");
            map.put("commCode", bo.getCommCode());
            map.put("devBuildingNo", bo.getCommCode() + "0000000" + (char) (i - 1 + 'a'));
            list.add(map);
        }
        return new JsonRespData("", 1, list);
    }

    @RequestMapping("resumeCard.x")
    @ResponseBody
    JsonRespData resumeCard(String cardNo) throws Exception {
        TblCardDimBo bo = ICardService.findTblCardDimById(cardNo);
        if (CardConstant.CARD_STATUS_DISABLED.equals(bo.getState())) {
            return new JsonRespData("", -1, "该卡已被挂失，请先去卡列表中恢复该卡，然后等半天再来恢复");
        }

        TblCommDimBo comm = ICommService.findTblCommDimById(bo.getCommCode());
        if (comm != null && CardConstant.CARD_VENDOR_LK_ID.equals(comm.getCardVendor())) {
            bo.setState(CardConstant.CARD_STATUS_DISABLED);
            Long timeStamp = System.currentTimeMillis();
            bo.setTimestamp(timeStamp);
            ICardService.save(bo);
            if (bo.getCardType().equals(CardConstant.CARD_TYPE_SUPPER)) {
                dataUpdateService.pushAndUpdate(timeStamp, CardUpdateData.CARD_PERMS, bo.getCommCode(), false, false, "", "");
            } else {
                List<TblCardPerms> cardPerms = ICardService.findCardPerms(cardNo);
                for (TblCardPerms cardPerm : cardPerms) {
                    cardPerm.setTimeStamp(timeStamp);
                    cardPerm.setEnable(CardConstant.CARD_PERM_BLACKLIST);
                    ICardService.save(cardPerm);
                    dataUpdateService.pushAndUpdate(timeStamp, CardUpdateData.CARD_PERMS, cardPerm.getDevBuildingNo(), true, false, "", "");
                }
            }
        } else {
            ICardService.removeCard(cardNo);
            ICardService.removeCardPerms(cardNo);
        }
        return new JsonRespData("", 1, "1");
    }

    @RequestMapping("delayEndDate.x")
    @ResponseBody
    JsonRespData delayEndDate(String cardNo, String endDate) throws Exception {
        TblCardDimBo bo = ICardService.findTblCardDimById(cardNo);
        if (bo == null)
            return new JsonRespData("", -1, cardNo + "卡号不存在");

        HashOperations hashOperations = stringTemplate.opsForHash();

        Date now = new Date();
        if (CardConstant.CARD_TYPE_NORMAL.equals(bo.getCardType())) {
            List<TblCardPerms> permsList = ICardService.findCardPerms(cardNo);
            for (TblCardPerms perm : permsList) {
                /* 将更新的数据条目时间戳推送给Redis */
                hashOperations.put(CardConstant.REDIS_CARD_TIMESTAMP, perm.getDevBuildingNo(), now.toString());
                perm.setEnable(CardConstant.CARD_PERM_WHITELIST);
                perm.setTimeStamp(now.getTime());
                ICardService.save(perm);
                dataUpdateService.pushAndUpdate(now.getTime(), CardUpdateData.CARD_PERMS, perm.getDevBuildingNo(), true, false, null, null);
            }
        } else {
            dataUpdateService.pushAndUpdate(now.getTime(), CardUpdateData.CARD_PERMS, bo.getCommCode(), false, false, null, null);
        }
        bo.setLastModifyTime(now);
        bo.setTimestamp(now.getTime());
        bo.setState(CardConstant.CARD_STATUS_RESUME);
        bo.setEndDate(DateUtil.stringDate(endDate, "yyyy-MM-dd"));
        ICardService.save(bo);
        return new JsonRespData("", 1, "");
    }
}
